#ifndef UNIX
# define GLEW_STATIC 1
#endif

#include <GL/glew.h>

#include <SDL/SDL.h>

#include "../../log.h"
#include "../../thread.h"

#include "../host.h"

#define WINTITLE "Yaupspe"

#define XRES 480
#define YRES 272

typedef struct
{
    Uint8 *keyStates;
    SDL_Event event;
#ifndef NO_THREAD
    Mutex mutex;
#endif
} SDLHost;

SDLHost host;

/* Initializes the window */
s32 host_winInit()
{
    GLenum err;

    /* Initialize SDL */
    _log(INF, GFX, "Initializing SDL");
    if (SDL_Init(SDL_INIT_VIDEO) == -1) {
        _log(ERR, GFX, "SDL initialization failed : %s", SDL_GetError());
        return -1;
    }

    _log(INF, GFX, "SDL initialized OK");

    /* Initialize SDL window */
    _log(INF, GFX, "Initializing SDL window");
    if (SDL_SetVideoMode(XRES, YRES, 32, SDL_OPENGL) == NULL) {
        _log(ERR, GFX, "SDL window creation failed : %s", SDL_GetError());
        return -1;
    }
    _log(INF, GFX, "Window initialized OK");
    host.keyStates = NULL;

    /* Initialize GLEW */
    _log(INF, GFX, "Initializing GLEW");
    err = glewInit();
    if (err != GLEW_OK) {
        _log(ERR, GFX, "GLEW initialization failed : %s", glewGetErrorString(err));
        return -1;
    }
    _log(INF, GFX, "GLEW initialized OK");

    host_setWinTitle(NULL);

    return 0;
}

void host_winQuit()
{
    SDL_Quit();
}

void host_setWinTitle(char *title)
{
    if (title)
    {
        char *fullTitle = malloc(sizeof(char) * (strlen(title) + strlen(WINTITLE) + 4));
        fullTitle[0] = '\0';
        strcpy(fullTitle, WINTITLE);
        strcat(fullTitle, " - ");
        strcat(fullTitle, title);
        SDL_WM_SetCaption(fullTitle, WINTITLE);
        free(fullTitle);
    }
    else
        SDL_WM_SetCaption(WINTITLE, WINTITLE);
}

/* Initialization function ran before creating threads */
s32 host_init()
{
#ifndef NO_THREAD
    cs_init(&host.mutex, "Host");
#endif
    return 0;
}

void host_free()
{
#ifndef NO_THREAD
    cs_free(&host.mutex);
#endif
}

void host_frameFinish()
{
    glFinish();
    SDL_GL_SwapBuffers();
}

void host_syncEvents()
{
    SDL_PumpEvents();
    cs_enter(&host.mutex);
    host.keyStates = SDL_GetKeyState(NULL);
    cs_leave(&host.mutex);
}

u8 host_isQuit()
{
    while (SDL_PollEvent(&host.event))
        if (host.event.type == SDL_QUIT || 
                (host.event.type == SDL_KEYDOWN &&
                 host.event.key.keysym.sym == SDLK_ESCAPE))
            return 1;
    return 0;
}

u32 host_getBut()
{
    u32 buttons = 0;

    cs_enter(&host.mutex);

    if (!host.keyStates) {
        cs_leave(&host.mutex);
        return 0;
    }

    if (host.keyStates[SDLK_SPACE])
        buttons |= (1 << CTRL_SELECT);
    if (host.keyStates[SDLK_RETURN])
        buttons |= (1 << CTRL_START);
    if (host.keyStates[SDLK_a])
        buttons |= (1 << CTRL_SQUARE);
    if (host.keyStates[SDLK_w])
        buttons |= (1 << CTRL_TRIANGLE);
    if (host.keyStates[SDLK_d])
        buttons |= (1 << CTRL_CIRCLE);
    if (host.keyStates[SDLK_s])
        buttons |= (1 << CTRL_CROSS);
    if (host.keyStates[SDLK_q])
        buttons |= (1 << CTRL_LTRIGGER);
    if (host.keyStates[SDLK_e])
        buttons |= (1 << CTRL_RTRIGGER);
    if (host.keyStates[SDLK_UP])
        buttons |= (1 << CTRL_UP);
    if (host.keyStates[SDLK_DOWN])
        buttons |= (1 << CTRL_DOWN);
    if (host.keyStates[SDLK_LEFT])
        buttons |= (1 << CTRL_LEFT);
    if (host.keyStates[SDLK_RIGHT])
        buttons |= (1 << CTRL_RIGHT);

    cs_leave(&host.mutex);

    return buttons;
}

